﻿#include "codeimagegenerator_p.h"
#include <QMap>
#include <QPainter>
#include <common/codeimagegenerate/codeimagegenerator.h>
#include <common/logger/logger.h>


CodeImageGeneratorPrivate::CodeImageGeneratorPrivate(CodeImageGenerator* q)
	: q_ptr(q), m_symbol(nullptr)
{
	// 初始化 Zint 符号
	m_symbol = ZBarcode_Create();
	if (!m_symbol)
	{
		LOG_ERROR("无法创建 Zint 符号实例");
	}
	isConfigured = false;
}

CodeImageGeneratorPrivate::CodeImageGeneratorPrivate(CodeImageGenerator* q, const CodeImageConfig& config)
	: q_ptr(q), m_config(config)
{
	// 初始化 Zint 符号
	m_symbol = ZBarcode_Create();
	if (!m_symbol)
	{
		LOG_ERROR("无法创建 Zint 符号实例");
	}
	setupSymbol(config);
	isConfigured = true;
}

CodeImageGeneratorPrivate::~CodeImageGeneratorPrivate()
{
	if (m_symbol)
	{
		ZBarcode_Delete(m_symbol);
		m_symbol = nullptr;
	}
}

QImage CodeImageGeneratorPrivate::generate(const QString& data)
{
	//如果已经设置过config，复用config（此分支应该是主要分支，因为我通过对象实例的方法，肯定是配置好config了）
	if (isConfigured)
	{
		return generate(data, m_config);
	}
	// 如果没有设置过config，则使用默认配置,先判断当前数据是否可以走默认条形码，否则走默认二维码
	CodeImageConfig config = checkCode128(data.toUtf8()).isEmpty() ? CodeImageConfig::defaultBarcode() : CodeImageConfig::defaultQRCode();

	LOG_INFO(QString("无参数配置生成策略，自动选择生成%1")
					 .arg(data.length())
					 .arg(config.getType() == BarcodeType::QR_CODE ? "二维码" : "条形码")
					 .toStdString());
	return generate(data, config);
}

QImage CodeImageGeneratorPrivate::generate(const QString& data, const CodeImageConfig& config)
{
	Q_Q(CodeImageGenerator);

	if (!m_symbol)
	{
		LOG_ERROR("Zint symbol 未实例化");
		return {};
	}

	if (data.trimmed().isEmpty())
	{
		LOG_ERROR("数据内容为空");
		return {};
	}

	//如果config和当前m_config一样,那么只清空上一次的bitmap缓存数据就行了，其他核心参数不需要重新设置;
	if (m_config == config)
	{
		ZBarcode_Clear(m_symbol);
	}
	//如果config更新了,那么需要重新设置符号参数
	else
	{
		// 重置符号状态
		ZBarcode_Reset(m_symbol);

		// 重新设置符号参数
		setupSymbol(config);
	}

	// symbol UNICODE_MODE默认开启，可以支持中文等多字节字符
	QByteArray dataBytes = data.toUtf8();
	// 根据不同的码类型，验证数据合法性
	QString validError = isValidData(dataBytes, config.getType());
	if (!validError.isEmpty())
	{
		LOG_ERROR(validError.toStdString());
		return {};
	}

	// 编码数据并生成bitmap位图
	int error = ZBarcode_Encode_and_Buffer(m_symbol,
										   reinterpret_cast<unsigned char*>(dataBytes.data()),
										   dataBytes.length(), 0);
	//错误码不等于0，代表有错误
	if (error != 0)
	{
		LOG_ERROR(QString("编码错误，错误原因%0,当前要生成的码类型:%1")
						  .arg(m_symbol->errtxt, barcodeTypeToString(config.getType()))
						  .toStdString());
		return {};
	}

	//将bitmap转为QImage
	QImage image = zintBufferToQImage(m_symbol);

	// 如果配置了图标且是二维码，添加图标
	if (config.getIcon().isValid() && (config.getType() == BarcodeType::QR_CODE))
	{
		image = addCenterIcon(image, config.getIcon());
	}
	return image;
}


void CodeImageGeneratorPrivate::setupSymbol(const CodeImageConfig& config)
{
	if (!m_symbol) return;

	// 设置符号类型
	switch (config.getType())
	{
	case BarcodeType::QR_CODE:
		m_symbol->symbology = BARCODE_QRCODE;
		m_symbol->option_2 = 0;// 设置版本为自动选择
		break;
	case BarcodeType::CODE_128:
		m_symbol->symbology = BARCODE_CODE128;
		break;
	case BarcodeType::EAN_13:
		m_symbol->symbology = BARCODE_EANX;
		m_symbol->option_1 = 13;// EAN-13
		break;
	case BarcodeType::MICRO_QR:
		m_symbol->symbology = BARCODE_MICROQR;
		m_symbol->option_2 = 0;//自动选择版本
		// Micro QR 的 容错依赖于版本，不同版本对数据的支持程度有差异;
		// Micro QR 支持的数据较小，如果手动指定容错，走检验时，很大可能会过不了检验；手动升级版本的话，维护复杂，且与逻辑差不多，故不设容错,自动选择
		m_symbol->option_1 = 0;//自动选择纠错级别
		break;
	default:
		m_symbol->symbology = BARCODE_QRCODE;
		break;
	}

	//设置安静区
	int ws_width = 0;                          // 水平安静区（每侧模块数）
	int ws_height = 0;                         // 垂直安静区（每侧模块数）
	bool needQuietZone = config.getQuietZone();// 是否启用安静区
	if (needQuietZone)
	{
		switch (config.getType())
		{
			// 二维条码
		case BarcodeType::QR_CODE:
			ws_width = 4;// 标准≥4，建议设4
			ws_height = 4;
			break;
		case BarcodeType::MICRO_QR:
			ws_width = 2;// 标准≥2，建议设2
			ws_height = 2;

			break;
			// 一维条码：EAN/UPC系列
		case BarcodeType::EAN_13:
			ws_width = 11;// 左侧≥11，右侧≥7，统一设11（满足两侧要求）
			ws_height = 7;// 标准≥7，建议设7
			break;
			// 一维条码：Code128/Code39
		case BarcodeType::CODE_128:
			ws_width = 10;// 标准≥10，建议设10
			ws_height = 5;// 标准≥5，建议设5
			break;
		default:
			ws_width = 4;// 默认按QR标准，避免过小
			ws_height = 4;
			break;
		}
	}

	// 应用安静区设置
	m_symbol->whitespace_height = m_config.getQuietZoneHeight() != 0 ? m_config.getQuietZoneHeight() : ws_height;
	m_symbol->whitespace_width = m_config.getQuietZoneWidth() != 0 ? m_config.getQuietZoneWidth() : ws_width;

	//当symbology>58时，宏定义里为二维码，可以设置容错级别
	if (m_symbol->symbology == BARCODE_QRCODE)
	{
		switch (config.getErrorLevel())
		{
		case ErrorCorrectionLevel::LOW:
			m_symbol->option_1 = 1;// L
			break;
		case ErrorCorrectionLevel::MEDIUM:
			m_symbol->option_1 = 2;// M
			break;
		case ErrorCorrectionLevel::QUARTILE:
			m_symbol->option_1 = 3;// Q
			break;
		case ErrorCorrectionLevel::HIGH:
			m_symbol->option_1 = 4;// H
			break;
		default:
			m_symbol->option_1 = 2;// 默认 M
			break;
		}

		// 如果没有指定生成后的尺寸，但是配置了图标，那么配置容错为最高
		if (!m_config.getSize().isValid() && m_config.getIcon().isValid())
		{
			m_symbol->option_1 = 4;
		}
		//设置安静区大小
	}
	else
	{
		// 设置是否显示文本，仅对一维条码有效
		m_symbol->show_hrt = config.getShowText() ? 1 : 0;
	}

	// 设置前景色，背景色
	// 生成 RGB 十六进制字符串（大写，无 # 前缀，如 "FF0000" 代表红色）zint需要这种参数
	// arg 参数说明：
	// - 第1个参数：颜色通道值（0-255）
	// - 第2个参数：最小宽度（2位，不足时补0，避免出现 "F0000" 这类不完整格式）
	// - 第3个参数：进制（16进制）
	// - 第4个参数：补位字符（'0'，确保不足2位时用0补全，而非空格）
	QString fgColorStr = QString("%1%2%3")
								 .arg(config.getFgColor().red(), 2, 16, QChar('0'))
								 .arg(config.getFgColor().green(), 2, 16, QChar('0'))
								 .arg(config.getFgColor().blue(), 2, 16, QChar('0'))
								 .toUpper();

	QString bgColorStr = QString("%1%2%3")
								 .arg(config.getBgColor().red(), 2, 16, QChar('0'))
								 .arg(config.getBgColor().green(), 2, 16, QChar('0'))
								 .arg(config.getBgColor().blue(), 2, 16, QChar('0'))
								 .toUpper();

	// fgColorStr.toUtf8().constData()：将 QString 转为 C 风格字符串（Zint 需 const char* 类型）
	strcpy_s(m_symbol->fgcolour, sizeof(m_symbol->fgcolour), fgColorStr.toUtf8().constData());
	strcpy_s(m_symbol->bgcolour, sizeof(m_symbol->bgcolour), bgColorStr.toUtf8().constData());

	//设置尺寸大小为传过来的
	if (config.getSize().isValid())
		m_config.setSize(config.getSize());
}

QImage CodeImageGeneratorPrivate::scaleQRImage() const
{
	int width = m_symbol->bitmap_width;
	int height = m_symbol->bitmap_height;
	unsigned char* pixels = new unsigned char[width * height * 3];
	try
	{
		{
			for (int y = 0; y < height; ++y)
			{
				for (int x = 0; x < width; ++x)
				{
					int offsetOrigin = y * width * 3 + x * 3;
					pixels[offsetOrigin] = m_symbol->bitmap[offsetOrigin];
					pixels[offsetOrigin + 1] = m_symbol->bitmap[offsetOrigin + 1];
					pixels[offsetOrigin + 2] = m_symbol->bitmap[offsetOrigin + 2];
				}
			}
		}
	}
	catch (const std::out_of_range& e)
	{
		LOG_ERROR("访问数组越界：", e.what());// 输出越界信息
		delete[] pixels;
		return {};
	}

	int m_width = m_config.getSize().width();
	int m_height = m_config.getSize().height();
	m_width = qMin(m_width, m_height);// 二维码取宽高最小值，保证是正方形
	if (m_width < width)
	{
		QImage image(pixels, m_width, m_width, QImage::Format_RGB888);
		QImage result = image.copy();// 深拷贝
		delete[] pixels;
		return result;
	}

	// 如何解决自定义二维码的尺寸：等比例缩放+白边
	int scaleFactor = static_cast<int>(std::floor(static_cast<double>(m_width) / width));// 计算等比例缩放因子
	int scaledWidth = width * scaleFactor;
	unsigned char* scaledPixels = new unsigned char[scaledWidth * scaledWidth * 3];
	try
	{
		// 原二维码等比例缩放
		// 临近像素插值
		// 原像素点映射到缩放后的像素点
		orignal2ScaledBitmap(width, pixels, scaleFactor, scaledWidth, scaledWidth, scaledPixels);
	}
	catch (const std::out_of_range& e)
	{
		LOG_ERROR("访问数组越界：", e.what());// 输出越界信息
		QImage image(pixels, m_width, m_width, QImage::Format_RGB888);
		QImage result = image.copy();// 深拷贝
		delete[] pixels;
		delete[] scaledPixels;
		return result;
	}

	unsigned char* finalPixels = new unsigned char[m_width * m_width * 3];

	//加上白边
	int margin = m_width - scaledWidth;// 白边的宽度
	int harfMargin = margin / 2;
	int modedMargin = margin % 2;

	try
	{
		// 缩放后的像素进行白边填充
		scaled2FilledWrite(m_width, m_width, scaledWidth, scaledWidth, scaledPixels, finalPixels, harfMargin, modedMargin, harfMargin, modedMargin);
	}
	catch (const std::out_of_range& e)
	{
		LOG_ERROR("访问数组越界：", e.what());// 输出越界信息
		QImage image(pixels, m_width, m_width, QImage::Format_RGB888);
		QImage result = image.copy();// 深拷贝
		delete[] pixels;
		delete[] scaledPixels;
		delete[] finalPixels;
		return result;
	}

	QImage image(finalPixels, m_width, m_width, m_width * 3, QImage::Format_RGB888);
	QImage result = image.copy();// 深拷贝
	delete[] pixels;             // 销毁原来指针
	delete[] scaledPixels;       // 销毁原来指针
	delete[] finalPixels;
	return result;
}

QImage CodeImageGeneratorPrivate::scaleBarcodeImage() const
{
	int width = m_symbol->bitmap_width;
	int height = m_symbol->bitmap_height;
	int m_width = m_config.getSize().width();
	int m_height = m_config.getSize().height();
	unsigned char* pixels = new unsigned char[width * height * 3];
	try
	{
		for (int y = 0; y < height; ++y)
		{
			for (int x = 0; x < width; ++x)
			{
				int offsetOrigin = y * width * 3 + x * 3;
				pixels[offsetOrigin] = m_symbol->bitmap[offsetOrigin];
				pixels[offsetOrigin + 1] = m_symbol->bitmap[offsetOrigin + 1];
				pixels[offsetOrigin + 2] = m_symbol->bitmap[offsetOrigin + 2];
			}
		}
	}
	catch (const std::out_of_range& e)
	{
		LOG_ERROR("访问数组越界：", e.what());// 输出越界信息
		delete[] pixels;
		return {};
	}

	int needToScale = 2;
	if (m_width < width)
	{
		LOG_WARN(QString("设定的宽度%1小于了条形码最小失真的尺寸，已自动调整为条形码最小宽度: %2px !")
						 .arg(m_width)
						 .arg(width));
		m_width = width;
		--needToScale;
	}
	if (m_height < height)
	{
		LOG_WARN(QString("设定的高度%1小于了条形码最小失真的尺寸，已自动调整为条形码最小高度: %2px !")
						 .arg(m_height)
						 .arg(height));
		m_height = height;
		--needToScale;
	}

	if (needToScale == 0)
	{
		QImage image(pixels, m_width, m_height, m_width * 3, QImage::Format_RGB888);
		QImage result = image.copy();// 深拷贝
		delete[] pixels;
		return result;
	}

	// 如何解决自定义条形码的尺寸：等比例缩放+白边
	int scaleFactorX = static_cast<int>(std::floor(static_cast<double>(m_width) / width));  // 计算等比例缩放因子
	int scaleFactorY = static_cast<int>(std::floor(static_cast<double>(m_height) / height));// 计算等比例缩放因子
	int scaleFactor = std::min(scaleFactorX, scaleFactorY);
	int scaledWidth = width * scaleFactor;
	int scaledHeight = height * scaleFactor;
	unsigned char* scaledPixels = new unsigned char[scaledWidth * scaledHeight * 3];

	// 原条形码等比例缩放
	// 临近像素插值
	try
	{
		orignal2ScaledBitmap(width, pixels, scaleFactor, scaledWidth, scaledHeight, scaledPixels);
	}
	catch (const std::out_of_range& e)
	{
		LOG_ERROR("访问数组越界：", e.what());// 输出越界信息
		QImage image(pixels, m_width, m_height, m_width * 3, QImage::Format_RGB888);
		QImage result = image.copy();// 深拷贝
		delete[] pixels;
		delete[] scaledPixels;
		return result;
	}


	unsigned char* finalPixels = new unsigned char[m_width * m_height * 3];

	// //加上白边
	int marginX = m_width - scaledWidth;  // 白边的宽度
	int marginY = m_height - scaledHeight;// 白边的宽度
	int harfMarginX = marginX / 2;
	int modedMarginX = marginX % 2;
	int harfMarginY = marginY / 2;
	int modedMarginY = marginY % 2;
	try
	{
		scaled2FilledWrite(m_width, m_height, scaledWidth, scaledHeight, scaledPixels, finalPixels, harfMarginX, modedMarginX, harfMarginY, modedMarginY);
	}
	catch (const std::out_of_range& e)
	{
		LOG_ERROR("访问数组越界：", e.what());// 输出越界信息
		QImage image(pixels, m_width, m_height, m_width * 3, QImage::Format_RGB888);
		QImage result = image.copy();// 深拷贝
		delete[] pixels;
		delete[] scaledPixels;
		delete[] finalPixels;

		return result;
	}
	QImage image(finalPixels, m_width, m_height, m_width * 3, QImage::Format_RGB888);
	QImage result = image.copy();// 深拷贝
	delete[] pixels;             // 销毁原来指针
	delete[] scaledPixels;       // 销毁原来指针
	delete[] finalPixels;
	return result;
}

QImage CodeImageGeneratorPrivate::zintBufferToQImage(zint_symbol* symbol) const
{
	if (!symbol || !symbol->bitmap || symbol->bitmap_width <= 0 || symbol->bitmap_height <= 0)
	{
		return {};
	}
	int width = symbol->bitmap_width;
	int height = symbol->bitmap_height;


	//如果没设置缩放尺寸，则直接返回
	if (!m_config.getSize().isValid())
	{
		unsigned char* zintBitmap = symbol->bitmap;
		QImage image(zintBitmap, width, height, width * 3, QImage::Format_RGB888);
		QImage result = image.copy();
		return result;
	}
	else if (m_symbol->symbology >= BARCODE_QRCODE)//二维码，矩阵
		return scaleQRImage();
	else
		return scaleBarcodeImage();//条形码
}

QImage CodeImageGeneratorPrivate::addCenterIcon(const QImage& barcode, const IconConfig& iconConfig)
{
	if (barcode.isNull() || !iconConfig.isValid())
	{
		return barcode;
	}

	// 初始化为生成bitmap的宽度
	int bitmapWidth = m_symbol->bitmap_width;

	// 如果设置了尺寸，则使用二维码缩放后的尺寸，而不是使用barcode（填充完白边后的尺寸）
	if (m_config.getSize().isValid())
	{
		int qrWidth = qMin(m_config.getSize().width(), m_config.getSize().height());
		int scaleFactor = static_cast<int>(std::floor(static_cast<double>(qrWidth) / m_symbol->bitmap_width));
		bitmapWidth = m_symbol->bitmap_width * scaleFactor;
	}

	//配置图标的尺寸
	const uint8_t& percent = iconConfig.getScalePercent();
	int logoSize = bitmapWidth * percent / 100;

	//配置图标的宽度
	uint8_t finalBorderWidth;
	uint8_t currentWidth = iconConfig.getBorderWidth();
	int maxBorderWidth = qMax(1, bitmapWidth / 50);// 最大为二维码尺寸的2%
	finalBorderWidth = qBound(0, static_cast<int>(currentWidth), maxBorderWidth);
	if (currentWidth != finalBorderWidth)
	{
		LOG_WARN("图标边框宽度超过最大尺寸的2%，已自动调整为" + QString::number(finalBorderWidth).toStdString());
	}

	QImage result = barcode;
	QPainter painter(&result);
	painter.setRenderHint(QPainter::SmoothPixmapTransform);
	QImage scaledLogo = iconConfig.getImage().scaled(logoSize, logoSize,
													 Qt::KeepAspectRatio, Qt::SmoothTransformation);

	// 计算图标位置（居中）
	int x = (barcode.width() - logoSize) / 2;
	int y = (barcode.height() - logoSize) / 2;

	// 绘制边框（如果需要）
	if (finalBorderWidth > 0)
	{
		int borderSize = logoSize + 2 * finalBorderWidth;
		int borderX = (barcode.width() - borderSize) / 2;
		int borderY = (barcode.height() - borderSize) / 2;
		painter.setBrush(Qt::white);
		painter.setPen(Qt::NoPen);

		// 绘制矩形或圆形边框
		if (iconConfig.isDrawRect())
			painter.drawRect(borderX, borderY, borderSize, borderSize);
		else
			painter.drawEllipse(borderX, borderY, borderSize, borderSize);
	}
	// 绘制图标
	painter.drawImage(x, y, scaledLogo);
	return result;
}

QList<BarcodeType> CodeImageGeneratorPrivate::getSupportedFormats()
{
	return {BarcodeType::QR_CODE, BarcodeType::CODE_128, BarcodeType::EAN_13, BarcodeType::MICRO_QR};
}

void CodeImageGeneratorPrivate::setCodeImageConfig(const CodeImageConfig& config)
{
	this->m_config = config;
	this->isConfigured = true;
	setupSymbol(m_config);
}

QString CodeImageGeneratorPrivate::checkCode128(const QString& data) const
{
	if (data.isEmpty())
	{
		return "CODE_128 :当前数据为空";
	}

	// 1. 检查是否包含非 ASCII 字符（中文等非法字符）
	for (const QChar& c: data)
	{
		// CODE_128 仅支持 ASCII 可打印字符（0x20-0x7E），排除控制字符
		if (c.unicode() < 0x20 || c.unicode() > 0x7E)
		{
			return "CODE_128 包含非法字符（仅支持英文、数字、常见标点）";
		}
	}

	// 2. 检查过滤后（合法字符）的长度是否超出限制
	// 注：此处长度按字符数计算（每个 ASCII 字符对应 1 个编码单元，与字节数一致）
	if (data.length() > 48)
	{
		return "CODE_128 数据长度超出限制（最大 48 个字符）";
	}
	// 全部验证通过
	return nullptr;
}
QString CodeImageGeneratorPrivate::checkEAN_13(const QString& data) const
{
	//必须是13位数字，且最后一位是校验位，由前12位计算最后一位，比较算出的和实际是否相同
	// 1. 验证长度为13位，且全为数字
	if (data.length() != 13) return QString("EAN-13 数据长度必须为13位，当前长度为%0").arg(data.length());
	bool isAllDigits = true;
	for (const QChar& c: data)
	{
		if (!c.isDigit())
		{
			isAllDigits = false;
			break;
		}
	}
	if (!isAllDigits)
	{
		return QString("EAN-13 数据必须全部为数字");
	}

	// 2. 验证校验位
	QString first12 = data.left(12);

	int sum = 0;
	for (int i = 0; i < 12; ++i)
	{
		int digit = first12[i].digitValue();
		sum += (i % 2 == 0) ? digit : digit * 3;// 奇数位乘1，偶数位乘3
	}
	int checksum = (10 - (sum % 10)) % 10;// 计算校验位

	int actualChecksum = data[12].digitValue();
	if (checksum != actualChecksum)
	{
		return QString("EAN-13 校验位错误，计算值：" + QString::number(checksum) + "，实际值：" + QString::number(actualChecksum));
	}
	return nullptr;// 校验位必须匹配
}
QString CodeImageGeneratorPrivate::isValidData(const QString& data, BarcodeType type) const
{
	switch (type)
	{
	case BarcodeType::QR_CODE:
		// QR Code 最大支持 4296 个字符
		return data.length() <= 4296 ? nullptr : "QR_CODE 数据长度超出限制";
	case BarcodeType::MICRO_QR:
		// 最大支持 128 个字符，因版本，容错不同，不同版本对字符的支持不同，此处取字符长度最大值检验，后面具体是否能生成，由zint检验
		return data.length() <= 35 ? nullptr : "MICRO_QR 数据长度超出限制";
	case BarcodeType::CODE_128: {
		return checkCode128(data);
	}

	case BarcodeType::EAN_13: {
		return checkEAN_13(data);
	}

	default:
		return !data.isEmpty() ? nullptr : "数据为空";
	}
}

QString CodeImageGeneratorPrivate::barcodeTypeToString(BarcodeType type)
{
	static const QMap<BarcodeType, QString> typeMap = {
			{BarcodeType::QR_CODE, "QR_CODE"},
			{BarcodeType::CODE_128, "CODE_128"},
			{BarcodeType::EAN_13, "EAN_13"},
			{BarcodeType::MICRO_QR, "MICRO_QR"}};
	auto it = typeMap.find(type);
	return (it != typeMap.end()) ? *it : "UNKNOWN_BARCODE_TYPE";
}

void CodeImageGeneratorPrivate::orignal2ScaledBitmap(int width, unsigned char* pixels, int scaleFactor, int scaledWidth, int scaledHeight, unsigned char* scaledPixels) const
{
	for (int y = 0; y < scaledHeight; ++y)
	{
		for (int x = 0; x < scaledWidth; ++x)
		{
			// 计算源图像中的对应像素位置
			int srcX = std::floor(x / scaleFactor);
			int srcY = std::floor(y / scaleFactor);

			int offsetOrigin = (y * scaledWidth + x) * 3;
			int offsetScaled = (srcY * width + srcX) * 3;

			scaledPixels[offsetOrigin] = pixels[offsetScaled];
			scaledPixels[offsetOrigin + 1] = pixels[offsetScaled + 1];
			scaledPixels[offsetOrigin + 2] = pixels[offsetScaled + 2];
		}
	}
}
void CodeImageGeneratorPrivate::scaled2FilledWrite(int m_width, int m_height, int scaledWidth, int scaledHeight, unsigned char* scaledPixels, unsigned char* finalPixels, int harfMarginX, int modedMarginX, int harfMarginY, int modedMarginY) const
{
	for (int y = 0; y < m_height; ++y)
	{
		for (int x = 0; x < m_width; ++x)
		{
			int offsetOrigin = y * m_width * 3 + x * 3;
			int offsetMargin = (y - harfMarginY - modedMarginY) * scaledWidth * 3 + (x - harfMarginX - modedMarginX) * 3;

			if (x >= harfMarginX + modedMarginX && x < scaledWidth + harfMarginX + modedMarginX && y >= harfMarginY + modedMarginY && y < scaledHeight + harfMarginY + modedMarginY)
			{
				finalPixels[offsetOrigin] = scaledPixels[offsetMargin];
				finalPixels[offsetOrigin + 1] = scaledPixels[offsetMargin + 1];
				finalPixels[offsetOrigin + 2] = scaledPixels[offsetMargin + 2];
			}
			else
			{
				finalPixels[offsetOrigin] = 255;
				finalPixels[offsetOrigin + 1] = 255;
				finalPixels[offsetOrigin + 2] = 255;
			}
		}
	}
}
